<?php

namespace app\logic\es;

use app\common\model\User;
use Elastic\Elasticsearch\Exception\ClientResponseException;
use Elastic\Elasticsearch\Exception\MissingParameterException;
use Elastic\Elasticsearch\Exception\ServerResponseException;
use Elastic\Elasticsearch\Response\Elasticsearch;
use Http\Promise\Promise;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Log;
use Throwable;

/**
 * 用户es操作模型
 */
class EsUser extends EsBase
{

    /**
     * 当前操作索引
     * @var string
     */
    protected string $index = "user";

    /**
     * 构造函数
     */
    public function __construct()
    {
        parent::__construct();

    }

    /**
     * 初始化索引配置
     * @throws ClientResponseException
     * @throws MissingParameterException
     * @throws ServerResponseException
     */
    public function initIndexSetting(): Elasticsearch|Promise|bool
    {
        $settings = [
            'analysis' => [
                'tokenizer' => [
                    'ik_max_word' => [
                        'type' => 'ik_max_word'
                    ],
                    'standard' => [
                        'type' => 'standard'
                    ],
                    'ngram_tokenizer' => [
                        'type' => 'edge_ngram',
                        'min_gram' => 2,
                        'max_gram' => 25,
                        'token_chars' => ['letter', 'digit']
                    ]
                ],
                'filter' => [
                    'english_stop' => [
                        'type' => 'stop',
                        'stopwords' => '_english_'  // 默认英语停用词列表
                    ],
                    'lowercase' => [
                        'type' => 'lowercase'  // 使所有文本转为小写
                    ]
                ],
                'analyzer' => [
                    'ik_max_analyzer' => [
                        'type' => 'custom',
                        'tokenizer' => 'ik_max_word'
                    ],
                    'english_analyzer' => [
                        'type' => 'custom',
                        'tokenizer' => 'standard',
                        'filter' => ['lowercase', 'english_stop']  // 使用英文停用词和小写转换
                    ],
                    'ngram_analyzer' => [
                        'type' => 'custom',
                        'tokenizer' => 'ngram_tokenizer',
                        'filter' => ['lowercase']  // 确保大小写不敏感
                    ]
                ]
            ]
        ];

        $mappings = [
            'properties' => [
                'nickname' => [
                    'type' => 'text',
                    'fields' => [
                        'chinese' => [
                            'type' => 'text',
                            'analyzer' => 'ik_max_analyzer'  // 中文分析器
                        ],
                        'english' => [
                            'type' => 'text',
                            'analyzer' => 'english_analyzer'  // 英文分析器
                        ],
                        'ngram' => [
                            'type' => 'text',
                            'analyzer' => 'ngram_analyzer'  // NGram分析器处理其他语言
                        ],
                        'keyword' => [
                            'type' => 'keyword'  // 精确匹配
                        ]
                    ],
                    'analyzer' => 'ngram_analyzer'  // 默认分析器
                ]
            ]
        ];

        return $this->ensureIndexExists($mappings, $settings);
    }


    /**
     * 导入数据
     * @param $uid
     * @return Elasticsearch|Promise
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     * @throws Throwable
     */
    public function import($uid): Elasticsearch|Promise
    {
        try {
            $fields = "id, username, nickname, avatar, birthday, gender, motto, account_type, is_creator, vip, vip_expire, join_ip, join_time";
            $data = User::initModel()->where(['status' => 'enable', 'id' => $uid])->field($fields)->find();

            if (!$data) throw new \Exception('动态不存在');

            $data = $data->toArray();

            return $this->update($uid, $data);
        } catch (Throwable $e) {
            Log::channel('es')->error($e->getMessage() . PHP_EOL . $e->getTraceAsString());
            throw $e;
        }
    }


    /**
     * 导入全部数据
     * @return bool
     * @throws ClientResponseException
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     * @throws ServerResponseException
     * @throws Throwable
     */
    public function importAll(): bool
    {
        $fields = "id, username, nickname, avatar, birthday, gender, motto, account_type, is_creator, vip, vip_expire, join_ip, join_time";
        $data = User::initModel()->where('status', 'enable')->field($fields)->select()->toArray();
        return $this->batches($data);
    }


}